/* 
 * google.js
 *
 * Code for handling various Google pages
 *
 * Copyright (c) 2010, Vishal Verma <vermavee@users.sf.net>
 */

try {
    var cur;
    var cursor;
    var global_atags;
    var global_search_links;

    service = get_service();
    if (service[0] == 'finance') {
        init_finance(service);
    } else if (service[0] == 'groups') {
        init_groups(service);
    } else if (service[0] == 'search') {
        init_search(service);
    } else {
        throw 0;
    }
} catch (e) {
}

/**
 * get_service
 *
 * get the type of service we are handling
 **/
function get_service()
{
    if (document.URL.indexOf('finance.google.com/group') > 0) {
        if (document.URL.indexOf('/topics') > 0)
            return [ 'finance', 'topics' ];
        else if (document.URL.indexOf('/thread/') > 0)
            return [ 'finance', 'threads' ];
        else
            return [ 'finance', 'unknown' ];
    } else if (document.URL.indexOf('google.com/finance') > 0) {
        if (document.URL.indexOf('?q=') > 0)
            return ['finance', 'ticker'];
        else
            return [ 'finance', 'main' ];
    } else if (document.URL.indexOf('groups.google.com') > 0) {
        if (document.URL.indexOf('/topics') > 0)
            return [ 'groups', 'topics' ];
        else if (document.URL.indexOf('/thread/') > 0)
            return [ 'groups', 'threads' ];
        else
            return [ 'groups', 'main' ];
    } else if (document.URL.indexOf('/search') > 0) {
        return [ 'search' ];
    }

    return [ 'unknown' ];
}

function init_finance(service)
{
    init_global_atags();
    window.onkeypress = finance_handler;

    function setup_finance_groups_logo() {
        var d = document.getElementsByClassName('padt0')[0];
        //l.style.top = d.parentNode.parentNode.parentNode.offsetTop + 'px';
        var l = setup_logo(d, d.parentNode.parentNode.parentNode.offsetTop);
    }

    if (service[1] == 'topics' || service[1] == 'threads') {
        document.body.getElementsByTagName('table')[0].getElementsByTagName('a')[0].href = '/';
    }

    if (service[1] == 'topics') {
        setup_finance_groups_logo();
        init_topics_generic();
    } else if (service[1] == 'threads') {
        setup_finance_groups_logo();
    } else {
        var d = document.getElementsByClassName('sfe-search')[0].parentNode;
        setup_logo(d);
    }
}

function init_groups(service)
{
    init_global_atags();
    var td = document.getElementsByClassName('gtopbar')[0];
    setup_logo(td);

    if (service[1] == 'topics') {
        window.onkeypress = topics_handler;
        init_topics_generic();
    } else if (service[1] == 'threads') {
        window.onkeypress = thread_handler;
    } else {
        window.onkeypress = group_handler;
    }
}

function init_search()
{
    var td = document.getElementsByClassName('rshdr')[0];
    setup_logo(td);

    global_search_links = document.getElementsByClassName("l");
    window.onkeypress = search_handler;

    cursor = create_cursor();
    var a = document.getElementsByClassName("l")[cur = 0];
    a.parentNode.insertBefore(cursor, a);
    a.focus();
}

function init_global_atags()
{
    global_atags = document.getElementsByTagName("A");
}

function setup_logo(container, force_top)
{
    var div = document.createElement('div');
    //div.style.display = 'inline-table';
    div.style.visible = false;
    var tw = document.createElement('div');
    tw.style.display = 'inline';
    tw.style.fontFamily = 'Georgia';
    tw.style.fontSize = '.75em';
    tw.appendChild(document.createTextNode('treated with '));
    div.appendChild(tw);

    var a = document.createElement('a');
    a.href = 'http://code.google.com/p/cro3';
    a.title = 'Press ? for help on what Chromium Oxide can do for you';
    var logo = document.createElement('img');
    logo.src = 'http://cro3.googlecode.com/svn/images/cro3.png';
    logo.parent_div = div;
    logo.container = container;
    logo.tw = tw;
    logo.force_top = force_top;
    logo.style.paddingRight = '2px';
    a.style.display = 'inline';
    a.style.verticalAlign = 'sub';
    //container.style.verticalAlign = 'bottom';
    a.appendChild(logo);
    div.appendChild(a);
    container.appendChild(div);

    logo.onload = function () {
        var div = this.parent_div;

        //console.log(tw.offsetWidth);
        //console.log(logo.offsetWidth);
        div.style.position = 'absolute';
        div.style.left = '100%';
        if (this.force_top)
            div.style.top = this.force_top + 'px';
        else
            div.style.top = this.container.offsetTop + 'px';

        // adding 2 to the margin to factor in the right padding above
        div.style.marginLeft = '-' + (tw.offsetWidth + this.offsetWidth + 2)
                                    + 'px';
        div.style.visible = true;
    }

    return div;
}

function create_cursor()
{
    return document.createTextNode("> ");
}

function init_topics_generic()
{
    cursor = create_cursor();
    td = document.getElementsByClassName("st")[cur = 0].parentNode.nextSibling.nextSibling;
    td.insertBefore(cursor, td.firstChild);
    td.getElementsByTagName("A")[0].focus();
}


var group_help = {
    'c': 'Compose a new topic',
    'd': 'Go to discussions',
};

function group_handler(e)
{
    var defer = true;
 
    // don't let TextArea and Input elements to grab event
    if (e.target.toString().indexOf('HTMLTextArea') > 0 ||
            e.target.toString().indexOf('HTMLInputElement') > 0)
        return true;

    switch (e.which) {
    case 63: // '?' help
        defer = false;
        show_help(group_help, true);
        break;

    case 99: // 'c' compose
        defer = false;
        document.getElementsByTagName('form')[3].submit();
        break;

    case 100: // 'd' discussions
        defer = false;
        var a = find_in_elements('Discussions', global_atags);
        if (a)
            window.location = a.href;
        break;

    }
    return defer;
}



var topics_help = {
    'c': 'Compose a new topic',
    'j': 'Next page of discussions',
    'k': 'Previous page of discussions',
    'n': 'Next topic',
    'p': 'Previous topic',
    's': 'Star topic',
    'Enter': 'Open topic'
};

function topics_handler(e)
{
    var defer = true;
 
    // don't let TextArea and Input elements to grab event
    if (e.target.toString().indexOf('HTMLTextArea') > 0 ||
            e.target.toString().indexOf('HTMLInputElement') > 0)
        return true;

    switch (e.which) {
    case 63: // '?' help
        defer = false;
        show_help(topics_help, true);
        break;

    case 99: // 'c' compose
        defer = false;
        var a = find_in_elements('new post', global_atags);
        if (a)
            window.location = a.href;
        break;

    case 106:   // 'j' go to next conversation
        defer = false;
        var a = find_in_elements('Older »', global_atags);
        if (a)
            window.location = a.href;
        break;

    case 107:   // 'k' go to previous conversation
        defer = false;
        var a = find_in_elements('« Newer', global_atags);
        if (a)
            window.location = a.href;
        break;

    case 110: // 'n' down
        defer = false;
        if (cur == document.getElementsByClassName("st").length - 1)
            break;

        document.getElementsByClassName("st")[cur].parentNode.
            nextSibling.nextSibling.removeChild(cursor);
        ++cur;
        var td = document.getElementsByClassName("st")[cur].parentNode.
            nextSibling.nextSibling;
        td.insertBefore(cursor, td.firstChild);
        td.getElementsByTagName("A")[0].focus();
        break;

    case 112: // 'p' up
        defer = false;
        if (cur == 0)
            break;

        document.getElementsByClassName("st")[cur].parentNode.
            nextSibling.nextSibling.removeChild(cursor);
        --cur;
        var td = document.getElementsByClassName("st")[cur].parentNode.
            nextSibling.nextSibling;
        td.insertBefore(cursor, td.firstChild);
        td.getElementsByTagName("A")[0].focus();
        break;

        /* disabling o because enter works
    case 111:   // 'o' open
        defer = false;
        window.location = 
        document.getElementsByClassName("st")[cur].parentNode.
            nextSibling.nextSibling.getElementsByTagName("A")[0].href;
        break;
        */
    case 115: // 's' star
        defer = false;
        document.getElementsByClassName("st")[cur].onclick();
    }
    return defer;
}


var thread_help = {
    'X': 'Toggle expand/collapse all messages',
    'c': 'Compose a new post',
    'd': 'Go to list of discussions',
    'j': 'Next older topic',
    'k': 'Next newer topic',
    'n': 'Next message',
    'p': 'Previous message',
    'o': 'Toggle expand/collapse current message',
    's': 'Star this topic'
};


function thread_handler(e)
{
    var defer = true;

    // don't let TextArea and Input elements to grab event
    if (e.target.toString().indexOf('HTMLTextArea') > 0 ||
            e.target.toString().indexOf('HTMLInputElement') > 0)
        return true;

    switch (e.which) {
    case 63: // '?' help
        defer = false;
        show_help(thread_help, true);
        break;

    case 88:    // 'X' expand/collapse messages toggle
        defer = false;
        var a = document.getElementById("expand_all_msgs_link").onmousedown
        if (a) 
            a();
        break;

    case 99: // 'c' compose
        defer = false;
        var a = find_in_elements('new post', global_atags);
        if (a)
            window.location = a.href;
        break;

    case 100:   // 'd' discussions
        defer = false;
        var service = get_service();
        if (service[0] == 'groups') {
            window.location = document.
                getElementsByClassName("seclnact")[0].href;
        } else if (service[0] == 'finance') {
        }
        break;

    case 106:   // 'j' previous (older) topic
        defer = false;
        var a = find_in_elements('Older topic »', global_atags);
        if (a)
            window.location = a.href;
        break;

    case 107:   // 'k' next (newer) topic
        defer = false;
        var a = find_in_elements('« Newer topic', global_atags);
        if (a)
            window.location = a.href;
        break;

    case 115: // 's' star
        defer = false;
        document.getElementsByClassName("st")[0].onclick();
    }

    return defer;
}



var search_help = {
    '/': 'Focus on the search box',
    'g': 'Jump to given page number',
    'j': 'Next page of results',
    'k': 'Previous page of results',
    'n': 'Next result',
    'p': 'Previous result',
    'Enter': 'Open the search result'
};
function search_handler(e)
{
    var defer = true;
 
    // don't let TextArea and Input elements to grab event
    if (e.target.toString().indexOf('HTMLTextArea') > 0 ||
            e.target.toString().indexOf('HTMLInputElement') > 0)
        return true;


    switch (e.which) {
    case 47:    // '/' go to search box
        defer = false;
        window.setTimeout(
                function () {
                    document.getElementsByName("q")[0].focus();
                    }, 10)
        break;

    case 63: // '?' help
        defer = false;
        show_help(search_help, true);
        break;

    case 103: // 'g' go to page
        var page = parseInt(window.prompt('Enter page number'));
        if (page == NaN || page <= 0)
            return;
        window.location = document.location.href.replace(/start=\d+/,'start=' +
                             ((page-1) * 10));
        break;

    case 106: // 'j' next page of results
        var next  = document.getElementsByClassName('cur')[0].nextSibling;
        if (next && next.tagName == "TD" && next.firstChild &&
                next.firstChild.href)
            window.location = next.firstChild.href;
        break;

    case 107: // 'k' previous page of results
        var previous  = document.getElementsByClassName('cur')[0].
            previousSibling;
        if (previous && previous.tagName == "TD" && previous.firstChild && 
                previous.firstChild.href)
            window.location = previous.firstChild.href;
        break;

    case 110: // 'n' down
        defer = false;
        if (cur == global_search_links.length - 1)
            break;

        global_search_links[cur].parentNode.removeChild(cursor);
        var a = global_search_links[++cur];
        a.parentNode.insertBefore(cursor, a);
        a.focus();
        break;

    case 112: // 'p' up
        defer = false;
        if (cur == 0)
            break;
        global_search_links[cur].parentNode.removeChild(cursor);
        var a = global_search_links[--cur];
        a.parentNode.insertBefore(cursor, a);
        a.focus();
        break;

        /* disabling o because enter works better
    case 111:   // 'o' open
        defer = false;
        window.location = global_search_links[cur].href;
        break;
        */
    }
    return defer;
}


function finance_handler(e)
{
    var defer = true;

    var finance_help;
    var service = get_service();
    
    if (service[1] == 'topics') {
        finance_help = {
            '/': 'Jump to the search box',
            'c': 'Start a new discussion',
            'n': 'Next topic',
            'p': 'Previous topic',
            's': 'Star this topic',
            'Enter': 'Open topic'
        };
    } else if (service[1] == 'threads') {
        finance_help = {
            '/': 'Jump to the search box',
            'c': 'Start a new discussion',
            'd': 'Go to discussions page',
            'j': 'Next topic',
            'k': 'Previous topic',
            'n': 'Next message',
            'p': 'Previous message',
            'o': 'Toggle expand/collpase current message',
            's': 'Star current topic',
        };
    } else if (service[1] == 'ticker') {
        finance_help = {
            '/': 'Jump to the search box',
            'd': 'Go to discussions page',
        };
    } else {
        finance_help = {
            '/': 'Jump to the search box'
        };
    }

    // don't let TextArea and Input elements to grab event
    if (e.target.toString().indexOf('HTMLTextArea') > 0 ||
            e.target.toString().indexOf('HTMLInputElement') > 0)
        return true;

    switch (e.which) {
    case 47:    // '/' go to search box
        defer = false;
        window.setTimeout(
                function () {
                    var q = document.getElementById("searchbox");
                    if (!q)
                        q = document.getElementsByName("q")[0];
                    q.focus();
                    q.select();
                }, 10);
        break;

    case 63: // '?' help
        defer = false;
        var help = show_help(finance_help, true);
        if (service[1] == 'ticker') {
            help.style.top = help.offsetHeight + 'px';
        }
        break;

    case 99:    // 'c' new discussion
        defer = false;
        document.getElementsByTagName('button')[0].onclick();
        break;

    case 100:   // 'd' discussions in go mode.
        defer = false;
        if (service[1] == 'ticker') {
            var a = find_in_elements('View all discussions', global_atags);
            if (a)
                window.location = a.href;
        } else if (service[1] == 'threads') {
            window.location = document.getElementsByClassName("on")[0].href;
        }

        break;

    case 106:   // 'j' go to next conversation
        if (service[1] == 'threads') {
            var a = document.getElementsByClassName("fl");
            // if we are at the newest topic
            if (a && a.length == 1)
                // the only link we have is next conversation
                window.location = a[0].href;
            else
                // the second link is next conversation
                window.location = a[1].href;
            defer = false;
        } // rest is deferred to topics/thread handler
        break;

    case 107:   // 'k' go to previous conversation
        if (service[1] == 'threads') {
            var a = document.getElementsByClassName("fl");
            if (a && a.length == 2)
                window.location = a[0].href;
            defer = false;
        } // rest is deferred to topics/thread handler
        break;
    }

    // if the keypress has already been handled
    if (!defer)
        return false;   // stop processing

    // keypress hasn't been handled. Handle it now.
    if (document.URL.indexOf('topics') != -1) {
        defer = topics_handler(e);  // defer to topics code for handling
                                    // finance topics
    } else if (document.URL.indexOf('thread') != -1) {
        defer = thread_handler(e);  // defer to threads code 
                            // for handling finance threads
    }

    return defer;
}

function find_in_elements(str, atags)
{
    var found = false;
    for (var a in atags) {
        if (atags[a].innerHTML && (atags[a].innerHTML.indexOf(str) != -1)) {
            found = true;
            break;
        }
    }

    if (found)
        return atags[a];
    else
        return null;
}

var help;
var help_save_handler;
var in_help;

function show_help(help_table, on)
{
    // make sure we are provided valid instructions
    if (typeof on == 'undefined')
        return;

    // if we are doing this for the first time
    if (typeof in_help == 'undefined') {
        in_help = on;   // in-help state is what user asked it to be
    } else if (on != in_help) {// if we are not already doing what is requested
        in_help = on;   // in-help state is what user asked it to be
    } else {            // otherwise
        return;         // return
    }

    if (!on) {
        if (typeof help != 'undefined')
            document.body.removeChild(help);

        // replace handler
        window.onkeypress = help_save_handler;
        window.onkeydown = null;
        return;
    }

    // remove handler
    help_save_handler = window.onkeypress;
    window.onkeypress = null;

    // Put the logo in
    var html = '<div style="text-align:center;margin-bottom:1em;"><img src="http://cro3.googlecode.com/svn/images/cro3.png"/></div>';

    // build html
    html += '<table style="font-size:13px">';
    for (var k in help_table) {
        html += '<tr><td style="text-align:right;color:Blue">' + k + '</td>';
        html += '<td>-</td>';
        html += '<td>' + help_table[k] + '</td></tr>';
    }
    html += '</table>';
    html +='<br/><div style="text-align:center;font-size:13px">Press Esc to close help</div>';

    /*
    // create dimmer
    var dimmer = document.createElement('div');
    dimmer.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;opacity:.5;background-color:gray;z-index:2';
    document.body.appendChild(dimmer);
    */

    // create container
    help = document.createElement('div');
    help.innerHTML = html;
    help.style.cssText = 'position:absolute; left:50%; top:50%; width:auto; height:auto; background-color: #C6E2FF; padding:20px; border:1px dashed'; // no opacity
    help.style.visible = false; // hide it till we center it
    window.onkeydown = function(e) {
        if (e.which == 27) {
            show_help(null, false);
        }
    }
    document.body.appendChild(help);

    // center the help
    help.style.cssText += 'margin:-' + (help.offsetHeight / 2) + 'px -' +
        (help.offsetWidth / 2) + 'px;';
    help.style.visible = true;

    return help;
}
